<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>企业公告智能监控大屏 - 公告来源分析</title>
    <script src="https://cdn.tailwindcss.com"></script>
    <script src="https://cdn.jsdelivr.net/npm/echarts@5.4.3/dist/echarts.min.js"></script>
    <style>
        body {
            background: linear-gradient(135deg, #2D3748 0%, #1A202C 100%);
            min-height: 100vh;
        }
        .chart-container {
            background: rgba(255, 255, 255, 0.05);
            backdrop-filter: blur(10px);
            border: 1px solid rgba(255, 255, 255, 0.1);
        }
        .kpi-card {
            background: linear-gradient(135deg, #4A5568 0%, #2D3748 100%);
            box-shadow: 0 8px 32px 0 rgba(0, 0, 0, 0.3);
        }
    </style>
</head>
<body class="text-white">
    <!-- 顶部导航 -->
    <header class="bg-black bg-opacity-20 backdrop-blur-md border-b border-white border-opacity-20 p-4">
        <div class="container mx-auto flex justify-between items-center">
            <h1 class="text-2xl font-bold">公告来源分析大屏</h1>
            <div class="flex space-x-6">
                <a href="/" class="text-white hover:text-blue-300">总览</a>
                <a href="/source" class="text-blue-300 font-semibold">来源分析</a>
                <a href="/sentiment" class="text-white hover:text-blue-300">情感分析</a>
                <a href="/risk" class="text-white hover:text-blue-300">风险监控</a>
                <a href="/system" class="text-white hover:text-blue-300">系统状态</a>
            </div>
            <div class="text-sm">
                <span id="update-time">更新时间: --</span>
            </div>
        </div>
    </header>

    <main class="container mx-auto p-6">
        <!-- KPI指标行 -->
        <div class="grid grid-cols-1 md:grid-cols-4 gap-6 mb-8">
            <div class="kpi-card rounded-xl p-6 text-center">
                <div class="text-3xl font-bold mb-2 text-blue-300" id="total-announcements">-</div>
                <div class="text-sm opacity-80">总公告数</div>
            </div>
            <div class="kpi-card rounded-xl p-6 text-center">
                <div class="text-3xl font-bold mb-2 text-green-300" id="total-companies">-</div>
                <div class="text-sm opacity-80">参与公司数</div>
            </div>
            <div class="kpi-card rounded-xl p-6 text-center">
                <div class="text-3xl font-bold mb-2 text-yellow-300" id="avg-daily">-</div>
                <div class="text-sm opacity-80">日均公告数</div>
            </div>
            <div class="kpi-card rounded-xl p-6 text-center">
                <div class="text-3xl font-bold mb-2 text-purple-300" id="peak-day">-</div>
                <div class="text-sm opacity-80">峰值日期</div>
            </div>
        </div>

        <!-- 图表区域 -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6 mb-8">
            <!-- 日发布趋势 -->
            <div class="chart-container rounded-xl p-6 lg:col-span-2">
                <h3 class="text-lg font-semibold mb-4">近30天公告发布趋势</h3>
                <div id="daily-trend-chart" style="height: 350px;"></div>
            </div>

            <!-- 交易所分布 -->
            <div class="chart-container rounded-xl p-6">
                <h3 class="text-lg font-semibold mb-4">交易所分布</h3>
                <div id="exchange-chart" style="height: 300px;"></div>
            </div>

            <!-- 小时分布 -->
            <div class="chart-container rounded-xl p-6">
                <h3 class="text-lg font-semibold mb-4">24小时发布分布</h3>
                <div id="hourly-distribution-chart" style="height: 300px;"></div>
            </div>
        </div>

        <!-- 详细统计表格 -->
        <div class="grid grid-cols-1 lg:grid-cols-2 gap-6">
            <!-- 每日统计表 -->
            <div class="chart-container rounded-xl p-6">
                <h3 class="text-lg font-semibold mb-4">每日统计详情</h3>
                <div class="overflow-x-auto max-h-96">
                    <table class="w-full text-sm">
                        <thead class="border-b border-gray-600">
                            <tr>
                                <th class="text-left py-2">日期</th>
                                <th class="text-left py-2">公告数</th>
                                <th class="text-left py-2">公司数</th>
                            </tr>
                        </thead>
                        <tbody id="daily-stats-table">
                        </tbody>
                    </table>
                </div>
            </div>

            <!-- 交易所统计表 -->
            <div class="chart-container rounded-xl p-6">
                <h3 class="text-lg font-semibold mb-4">交易所统计详情</h3>
                <div class="overflow-x-auto max-h-96">
                    <table class="w-full text-sm">
                        <thead class="border-b border-gray-600">
                            <tr>
                                <th class="text-left py-2">交易所</th>
                                <th class="text-left py-2">公告数</th>
                                <th class="text-left py-2">占比</th>
                                <th class="text-left py-2">公司数</th>
                            </tr>
                        </thead>
                        <tbody id="exchange-stats-table">
                        </tbody>
                    </table>
                </div>
            </div>
        </div>
    </main>

    <script>
        let charts = {};
        let dailyData = [];
        
        document.addEventListener('DOMContentLoaded', function() {
            loadData();
            setInterval(loadData, 60000); // 每分钟刷新
        });

        async function loadData() {
            try {
                await Promise.all([
                    loadDailyStats(),
                    loadExchangeStats(),
                    loadHourlyDistribution()
                ]);
                updateKPIs();
                document.getElementById('update-time').textContent = `更新时间: ${new Date().toLocaleString()}`;
            } catch (error) {
                console.error('加载数据失败:', error);
            }
        }

        async function loadDailyStats() {
            const response = await fetch('/api/source/daily-stats?days=30');
            dailyData = await response.json();
            
            updateDailyTrendChart(dailyData);
            updateDailyStatsTable(dailyData);
        }

        async function loadExchangeStats() {
            const response = await fetch('/api/source/exchange-stats');
            const data = await response.json();
            
            updateExchangeChart(data);
            updateExchangeStatsTable(data);
        }

        async function loadHourlyDistribution() {
            const response = await fetch('/api/source/hourly-distribution');
            const data = await response.json();
            
            updateHourlyDistributionChart(data);
        }

        function updateKPIs() {
            if (dailyData.length === 0) return;
            
            const totalAnnouncements = dailyData.reduce((sum, item) => sum + item.announcement_count, 0);
            const totalCompanies = Math.max(...dailyData.map(item => item.company_count));
            const avgDaily = Math.round(totalAnnouncements / dailyData.length);
            const peakDay = dailyData.reduce((max, item) => 
                item.announcement_count > max.announcement_count ? item : max
            );
            
            document.getElementById('total-announcements').textContent = totalAnnouncements.toLocaleString();
            document.getElementById('total-companies').textContent = totalCompanies.toLocaleString();
            document.getElementById('avg-daily').textContent = avgDaily.toLocaleString();
            document.getElementById('peak-day').textContent = peakDay.date;
        }

        function updateDailyTrendChart(data) {
            const chartDom = document.getElementById('daily-trend-chart');
            if (!charts.dailyTrend) {
                charts.dailyTrend = echarts.init(chartDom);
            }
            
            const option = {
                tooltip: {
                    trigger: 'axis',
                    axisPointer: { type: 'cross' }
                },
                legend: {
                    data: ['公告数', '公司数'],
                    textStyle: { color: '#fff' }
                },
                xAxis: {
                    type: 'category',
                    data: data.map(item => item.date),
                    axisLabel: { color: '#fff', rotate: 45 }
                },
                yAxis: [
                    {
                        type: 'value',
                        name: '公告数',
                        position: 'left',
                        axisLabel: { color: '#fff' },
                        nameTextStyle: { color: '#fff' }
                    },
                    {
                        type: 'value',
                        name: '公司数',
                        position: 'right',
                        axisLabel: { color: '#fff' },
                        nameTextStyle: { color: '#fff' }
                    }
                ],
                series: [
                    {
                        name: '公告数',
                        type: 'line',
                        yAxisIndex: 0,
                        data: data.map(item => item.announcement_count),
                        smooth: true,
                        itemStyle: { color: '#60A5FA' },
                        areaStyle: { color: 'rgba(96, 165, 250, 0.3)' }
                    },
                    {
                        name: '公司数',
                        type: 'line',
                        yAxisIndex: 1,
                        data: data.map(item => item.company_count),
                        smooth: true,
                        itemStyle: { color: '#34D399' }
                    }
                ]
            };
            
            charts.dailyTrend.setOption(option);
        }

        function updateExchangeChart(data) {
            const chartDom = document.getElementById('exchange-chart');
            if (!charts.exchange) {
                charts.exchange = echarts.init(chartDom);
            }
            
            const colors = ['#60A5FA', '#34D399', '#F87171', '#FBBF24', '#A78BFA'];
            
            const option = {
                tooltip: {
                    trigger: 'item',
                    formatter: '{a} <br/>{b}: {c} ({d}%)'
                },
                legend: {
                    orient: 'vertical',
                    left: 'left',
                    textStyle: { color: '#fff' }
                },
                series: [{
                    name: '交易所分布',
                    type: 'pie',
                    radius: ['50%', '70%'],
                    center: ['60%', '50%'],
                    avoidLabelOverlap: false,
                    label: {
                        show: true,
                        color: '#fff'
                    },
                    data: data.map((item, index) => ({
                        value: item.announcement_count,
                        name: item.exchange,
                        itemStyle: { color: colors[index % colors.length] }
                    }))
                }]
            };
            
            charts.exchange.setOption(option);
        }

        function updateHourlyDistributionChart(data) {
            const chartDom = document.getElementById('hourly-distribution-chart');
            if (!charts.hourly) {
                charts.hourly = echarts.init(chartDom);
            }
            
            const option = {
                tooltip: { trigger: 'axis' },
                xAxis: {
                    type: 'category',
                    data: data.map(item => `${item.hour}:00`),
                    axisLabel: { color: '#fff' }
                },
                yAxis: {
                    type: 'value',
                    axisLabel: { color: '#fff' }
                },
                series: [{
                    name: '公告数',
                    type: 'bar',
                    data: data.map(item => item.count),
                    itemStyle: {
                        color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
                            { offset: 0, color: '#60A5FA' },
                            { offset: 1, color: '#1E3A8A' }
                        ])
                    }
                }]
            };
            
            charts.hourly.setOption(option);
        }

        function updateDailyStatsTable(data) {
            const tbody = document.getElementById('daily-stats-table');
            tbody.innerHTML = data.map(item => `
                <tr class="border-b border-gray-700 hover:bg-white hover:bg-opacity-5">
                    <td class="py-2">${item.date}</td>
                    <td class="py-2">${item.announcement_count.toLocaleString()}</td>
                    <td class="py-2">${item.company_count.toLocaleString()}</td>
                </tr>
            `).join('');
        }

        function updateExchangeStatsTable(data) {
            const tbody = document.getElementById('exchange-stats-table');
            tbody.innerHTML = data.map(item => `
                <tr class="border-b border-gray-700 hover:bg-white hover:bg-opacity-5">
                    <td class="py-2">${item.exchange}</td>
                    <td class="py-2">${item.announcement_count.toLocaleString()}</td>
                    <td class="py-2">${item.percentage}%</td>
                    <td class="py-2">${item.company_count.toLocaleString()}</td>
                </tr>
            `).join('');
        }

        // 响应式处理
        window.addEventListener('resize', function() {
            Object.values(charts).forEach(chart => {
                if (chart) chart.resize();
            });
        });
    </script>
</body>
</html> 